package com.linq.cool.system.controller;

import com.linq.cool.api.vo.LoginUser;
import com.linq.cool.common.constants.CacheConstants;
import com.linq.cool.common.constants.UserConstants;
import com.linq.cool.common.core.domain.BaseController;
import com.linq.cool.common.core.domain.PageVO;
import com.linq.cool.common.core.domain.Result;
import com.linq.cool.common.core.utils.JwtUtils;
import com.linq.cool.common.core.utils.SecurityUtils;
import com.linq.cool.common.core.utils.ServletUtils;
import com.linq.cool.common.core.utils.StringUtils;
import com.linq.cool.common.log.annotation.Log;
import com.linq.cool.common.log.enums.BusinessType;
import com.linq.cool.common.redis.service.RedisService;
import com.linq.cool.common.security.annotation.PreAuthorize;
import com.linq.cool.system.dto.SysOnlineUserQueryDTO;
import com.linq.cool.system.service.SysOnlineUserService;
import com.linq.cool.system.vo.SysOnlineUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @Author: yqlin
 * @Date: 2021/1/29 08:24
 * @Description: 在线用户监控
 * @Version: 1.0.0
 */
@RestController
@RequestMapping("online")
public class SysOnlineUserController extends BaseController {
    @Autowired
    private SysOnlineUserService sysOnlineUserService;
    @Autowired
    private RedisService redisService;

    public static void main(String[] args) {
        String key = "login_tokens:asafasfsdfs";
        System.out.println(key.replace(CacheConstants.LOGIN_TOKEN_KEY, ""));
    }

    @PreAuthorize(hasPerm = "monitor:online:list")
    @GetMapping("/list")
    public Result<?> list(SysOnlineUserQueryDTO dto) {
        Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        List<SysOnlineUser> onlineUsers = new ArrayList<>();
        for (String key : keys) {
            String token = key.replace(CacheConstants.LOGIN_TOKEN_KEY, "");
            Integer loginType = JwtUtils.getLoginType(token);
            if (UserConstants.StateEnum.LOGIN_TYPE_SYSTEM.getCode().equals(loginType)) {
                LoginUser user = redisService.getCacheObject(key);
                if (StringUtils.isNotEmpty(dto.getIp()) && StringUtils.isNotEmpty(dto.getUsername())) {
                    if (StringUtils.equals(dto.getIp(), user.getLoginIp()) && StringUtils.equals(dto.getUsername(), user.getUsername())) {
                        onlineUsers.add(sysOnlineUserService.getByParams(dto.getIp(), dto.getUsername(), user));
                    }
                } else if (StringUtils.isNotEmpty(dto.getIp())) {
                    if (StringUtils.equals(dto.getIp(), user.getLoginIp())) {
                        onlineUsers.add(sysOnlineUserService.getByIp(dto.getIp(), user));
                    }
                } else if (StringUtils.isNotEmpty(dto.getUsername())) {
                    if (StringUtils.equals(dto.getUsername(), user.getUsername())) {
                        onlineUsers.add(sysOnlineUserService.getByUsername(dto.getUsername(), user));
                    }
                } else {
                    onlineUsers.add(sysOnlineUserService.loginUserToOnlineUser(user));
                }
            }
        }
        Collections.reverse(onlineUsers);
        return Result.ok(new PageVO().setTotal((long) onlineUsers.size()).setRecords(onlineUsers));
    }

    /**
     * 强退用户
     */
    @PreAuthorize(hasPerm = "monitor:online:forceLogout")
    @Log(moduleTitle = "在线用户", businessType = BusinessType.FORCE)
    @DeleteMapping("{tokenId}")
    public Result<?> forceLogout(@PathVariable String tokenId) {
        if (tokenId.equals(SecurityUtils.getToken(ServletUtils.getRequest()))) {
            return Result.fail("不能强退自己,请选择手动退出");
        }
        redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
        return Result.ok();
    }
}
